package index;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeSet;

import tools.Normalizer;

public class IndexMap implements Index {

	private String corpus;
	private Normalizer norm;
	private boolean removeStopWords;

	// map qui contient pour chaque document, un map de tf-idf pour chaque terme
	protected HashMap<String, HashMap<String, Float>> dictionnaireDeMot;
	protected ArrayList<String> requetes;
	private DocumentAnalyser analyser;
	protected ArrayList<String> result;

/*	public IndexMap() {
		dictionnaireDeMot = new HashMap<String, HashMap<String, Float>>();
		requetes = new ArrayList<String>();
		analyser = new DocumentAnalyser();
		result = new ArrayList<String>();
	}
*/
	
	public IndexMap(String corpus, Normalizer norm, boolean removeStopWords) {
		dictionnaireDeMot = new HashMap<String, HashMap<String, Float>>();
		requetes = new ArrayList<String>();
		analyser = new DocumentAnalyser(corpus, norm, removeStopWords);
		result = new ArrayList<String>();
		this.norm = norm;
		this.removeStopWords = removeStopWords;
		construireIndex(corpus, norm, removeStopWords);
	}

	@Override
	public void construireIndex(String corpus, Normalizer norm,
			boolean removeStopWords) {
		/*
		 * on calcule pour chaque fichier dans le corpus, le poid de chaque
		 * terme dans ce document
		 */
		this.norm = norm;
		this.removeStopWords = removeStopWords;
		this.corpus = corpus;
		File dossier = new File(corpus);
		String[] docs = dossier.list();
		if (docs == null){
			System.out.println("impossible de lire le corpus : " + dossier.getAbsolutePath());
			return;
		}
		int documentNb = analyser.getNombreDocument();
		System.out.println("documentNb : " + documentNb);
		HashMap<String, Integer> df;
		try {
			df = this.analyser.getDocumentFrequency();
			System.out.println("DocumentFrequency : " + df.size());

			File f;
			for (String docName : docs) {
				f = new File(corpus + docName);
				if (f.isDirectory()) {
					construireIndex(corpus + docName + '/', norm,
							removeStopWords);
				} else {
					HashMap<String, Float> tfidf = this.analyser.getTfIdf(
							corpus + docName, df);
					this.dictionnaireDeMot.put(docName, tfidf);
				}
			}

			System.out.println("dictionnaireNb : "
					+ this.dictionnaireDeMot.size());

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/*
	@Override
	public void setRequete(String requete) {
		String[] requetesTemps = requete.split(" ");

		for (int i = 0; i < requetesTemps.length; i++) {
			this.requetes.add(requetesTemps[i]);
		}
	}
	

	@Override
	public void calculSimularity(int nbAfficher) {

		final HashMap<String, Double> scores = new HashMap<String, Double>();

		System.out.println("Taille dictionnaire : "
				+ this.dictionnaireDeMot.size());
		
		//calcul des poids des termes de la requete dans le corpus total
		double numr = 0;
		HashMap<String, Double> wiq = new HashMap<String, Double>();
		for(String terme : requetes){
			//TODO alienor
		}

		
		//  Pour chaque document, on calcule la somme des poids de chaque terme
		// dans la requete
		 
		double den = 0, doc = 0;
		for (String docName : this.dictionnaireDeMot.keySet()) {
			HashMap<String, Float> poids = this.dictionnaireDeMot.get(docName);

			// La somme de scores de t1, t2, t3..., tn
			for (String mot : this.requetes) {
				if (poids.containsKey(mot)) {
					den += poids.get(mot);
					doc += (poids.get(mot) * poids.get(mot));
				}
			}
			if (doc > 0)
				scores.put(docName, (den / (Math.sqrt(doc) * requetes.size())));
			doc = 0;
			den = 0;
		}

		// on cree un comparateur qui compare l'angle
		TreeSet<String> files = new TreeSet<String>(new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				// on retourne l'ordre DESCENDANT
				if (scores.get(o1) <= scores.get(o2)) {
					return 1;
				} else {
					return -1;
				}
			}

		});

		// on ordonne le resultat
		files.addAll(scores.keySet());
		Object[] liste = files.toArray();
		System.out.println("scores : " + scores.size());
		System.out.println("scores.keySet : " + scores.keySet().size());

		System.out.println("files : " + files.size() + "; liste : "
				+ liste.length);

		if (nbAfficher > liste.length) {
			nbAfficher = liste.length;
		}
		if (nbAfficher > files.size()) {
			nbAfficher = files.size();
		}

		// on ajoute les resultats a la liste qui sera affichee
		for (int i = 0; i < nbAfficher; i++) {
			this.result.add((String) liste[i] + "\t" + scores.get(liste[i]));
		}
	}

	/*
	@Override
	public ArrayList<String> getResult() {
		return this.result;
	}
*/
	@Override
	public void reinitialiseIndex() {
		this.requetes = new ArrayList<String>();
		this.result = new ArrayList<String>();
	}
/*
	@Override
	public ArrayList<String> relevanceFeedBack(ArrayList<String> result,
			int nbDoc, int nbTermes) {
		// TODO Auto-generated method stub
		return null;
	}
	*/
	
	@Override
	public Normalizer getNorm() {
		return norm;
	}
	
	@Override
	public boolean isRemoveStopWords() {
		return removeStopWords;
	}

	@Override
	public HashMap<String, Integer> getDocumentFrequency() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public HashMap<String, Integer> getDfs() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public float getMaxIDF() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public HashMap<String, Integer> getMaxTFs() {
		// TODO Auto-generated method stub
		return null;
	}


}
